import axios from 'axios'
import type { ToolMeta } from '@/tools'

// Hardcoded OpenAI API configuration
const OPENAI_BASE_URL = 'https://x666.me/v1';
const OPENAI_API_KEY: string = 'sk-qVxX369CIGKKJsgPEjpYQrJ7msTA61OkKTncustm7DaaziHj'; // <-- IMPORTANT: Replace with your actual API key
const OPENAI_MODEL = 'gemini-2.5-flash-preview-05-20';

interface ChatMessage {
  role: 'user' | 'assistant' | 'tool'
  content: string
  name?: string
}

/**
 * Calls the OpenAI Chat Completions API with a hardcoded configuration.
 * @param messages The chat history.
 * @param tools The list of available tools for the model to use.
 * @param currentPage The current page path to provide context to the AI.
 * @returns The response content from the AI.
 */
export async function getOpenAICompletion(
  messages: ChatMessage[],
  tools: ToolMeta[],
  currentPage: string
) {
  if (OPENAI_API_KEY === 'YOUR_API_KEY_HERE') {
    return { content: '错误：尚未配置 OpenAI API Key。请在 src/openai/index.ts 文件中进行配置。' }
  }

  const formattedTools = tools.map(t => ({
    type: 'function',
    function: {
      name: t.name,
      description: t.description,
      parameters: { type: 'object', properties: {}, required: [] },
    },
  }))
  
  // System message to provide context to the AI
  const systemMessage = {
      role: 'system',
      content: `You are ChatGPT, a professional AI agent embedded in a Vue web-app. The user is currently on the page: '${currentPage}'. A catalogue of JavaScript functions (\"tools\") is available for you. You can and SHOULD call a tool whenever it is necessary to fulfil the user's request.\n\nHOW TO CALL A TOOL\nIf a tool is required, reply **EXACTLY** with valid JSON of the form:\n{ \"tool\": \"<toolName>\", \"args\": { /* parameters */ } }\nDo NOT wrap the JSON in markdown. Do NOT add any other keys.\n • For tools that take a single positional parameter (e.g. an id), supply it inside args, e.g. { \"tool\": \"routerToTaskExecuteView\", \"args\": { \"id\": 123 } }.\n • If no arguments are needed, use an empty object: { \"tool\": \"routerToTaskView\", \"args\": {} }.\n\nAFTER A TOOL RUNS\nThe frontend will execute the function and send you its result as a tool message. Based on the new state you can decide whether another tool is required.\n\nEND OF WORKFLOW\nWhen everything is finished and **no further tool calls are required**, reply with:\n{ \"done\": true }\nAgain, no markdown or extra text.\n\nIMPORTANT RULES
1. The response MUST be pure JSON exactly matching the schema (no markdown, no additional text).
2. If you need to communicate something to the human, call the tool 'showNotification' instead of writing natural language in your response.
3. Always think step-by-step about whether you need to call a tool to satisfy the user's request.`
  };
  
  // 仅过滤掉 name 为空的 tool 消息，避免 API 校验错误
  const filteredMessages = messages.filter((m: any) => {
    if (!m.content || String(m.content).trim() === '') return false // discard empty
    if (m.role === 'tool' && !m.name) return false // invalid tool message
    return true
  });

  const messagesWithSystem = [systemMessage, ...filteredMessages];

  try {
    const response = await axios.post(
      `${OPENAI_BASE_URL}/chat/completions`,
      {
        model: OPENAI_MODEL,
        messages: messagesWithSystem,
        tools: formattedTools,
        tool_choice: 'auto',
      },
      {
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${OPENAI_API_KEY}`,
        },
      }
    )

    const assistantMessage = response.data.choices[0].message
    if (assistantMessage.tool_calls) {
      const toolCall = assistantMessage.tool_calls[0]
      // Important: OpenAI returns arguments as a string, must be parsed
      const toolArgs = JSON.parse(toolCall.function.arguments || '{}')

      return {
        content: JSON.stringify({
          tool: toolCall.function.name,
          args: toolArgs,
          callId: toolCall.id || toolCall.tool_call_id || undefined
        }),
      }
    }

    return { content: assistantMessage.content || "" }
  } catch (error: any) {
    console.error('OpenAI API call failed:', error)
    return {
      content: `请求 OpenAI API 失败: ${error.response?.data?.error?.message || error.message}`,
    }
  }
} 